from common_data import *
from permission import *
from twisted.web import xmlrpc
from twisted.names import dns
from twisted.python import log

class XMLRPC_ResourceRecordResource( xmlrpc.XMLRPC ):
    _permissions = {
        'addResourceRecord':        PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'delResourceRecord':        PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'getResourceRecordByID':    PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'getResourceRecordByName':  PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
        'listResourceRecords':      PERMISSION_REQUIREMENT_GLOBAL_ADMIN,
    }
    
    def __init__(self):
        """ load config
        """
        log.msg( 'Resource Record resource init' )
        xmlrpc.XMLRPC.__init__(self)
        
    def xmlrpc_listResourceRecords(self):
        """return list of resource records"""
        
        try:
            rrs = ResourceRecord.select( orderBy=ResourceRecord.q.id )
        except:
            log.err( 'could not retrieve resource records' )
            log.err()
            raise xmlrpc.Fault( 123, 'could not retrieve resource records' )
        
        return list( ( rr.id, rr.name ) for rr in rrs )
    
    xmlrpc_listResourceRecords.signature = [['array']]
    
    def xmlrpc_getResourceRecordsByName(self, rr_name ):
        """return resource record attributes"""
        
        if not str( rr_name ):
            raise xmlrpc.Fault( 123, 'invalid argument' )
                   
        try:
            rrs = list( ResourceRecord.selectBy( name = str( rr_name ) ) )
        except IndexError:
            raise xmlrpc.Fault( 123, 'resource record not found' )
        except:
            log.err( 'could not retrieve resource records. rr_name: %s' % str( rr_name ) )
            log.err()
            raise xmlrpc.Fault( 123, 'could not retrieve resource records' )
        
        result = list()
            
        for rr in rrs:
            result.append( self.rrResultToDict( rr ) )

        return result
    
    xmlrpc_getResourceRecordsByName.signature = [['array','string']]           
            
    def xmlrpc_getResourceRecordByID(self, rr_id ):
        """return resource record attributes"""
        
        if not int( rr_id ):
            raise xmlrpc.Fault( 123, 'invalid argument' )
        
        rr = getResourceRecordById( rr_id )
                    
        return self.rrResultToDict( rr )
    
    xmlrpc_getResourceRecordByID.signature = [['array','string']]
    
    def xmlrpc_addResourceRecord(self, env_id, name, ttl, type, klass, value ):
        """create new resource record"""
        
        if not int( env_id ) or not str( name ) or not int( ttl ) or not str( type ) or not str( klass ) or not str( value ):
            raise xmlrpc.Fault( 123, 'invalid argument' )
        
        if not str( type ) in dns.QUERY_TYPES.values():
            raise xmlrpc.Fault( 123, 'invalid type argument' )
        
        if not str( klass ) in dns.QUERY_CLASSES.values():
            raise xmlrpc.Fault( 123, 'invalid class argument' )
        
        if not Environment.select( Environment.q.id == int( env_id ) ).count():
            raise xmlrpc.Fault( 123, 'invalid environment argument' )
        
        try:
            rr = ResourceRecord( name = str( name ), ttl = int( ttl ), type = str( type ), klass = str( klass ), value = str( value ), environment = int( env_id ) )
        except:
            log.err( 'could not create resource record: name = %s, ttl = %d, type = %s, klass = %s, value = %s, environment = %d' % ( str( name ), int( ttl ), str( type ), str( klass ), str( value ), int( env_id ) ) )
            log.err()
            raise xmlrpc.Fault( 123, 'could not create resource record' )
        
        return rr.id
    
    xmlrpc_addResourceRecord.signature = [['int','int','string','int','string','string','string']]
    
    def xmlrpc_delResourceRecord(self, rr_id ):
        """delete existing resource record"""
        
        if not int( rr_id ):
            raise xmlrpc.Fault( 123, 'invalid arguments' )
        
        rr = getResourceRecordById( rr_id )
        
        try:
            rr.destroySelf()
        except:
            log.err( 'could not delete resource record: rr_id = %d' % int( rr_id ) )
            log.err()
            raise xmlrpc.Fault( 123, 'could not delete resource record' )
        
        return True
    
    xmlrpc_delResourceRecord.signature = [['bool','int']]
        
    def rrResultToDict(self, rr ):
        result = dict()
        result['name'] = rr.name
        result['ttl'] = rr.ttl
        result['type'] = rr.type
        result['klass'] = rr.klass
        result['value'] = rr.value
        result['environment'] = rr.environment.id
        
        return result